// 实现这个项目的构建任务
const {src, dest,parallel,series, watch } = require('gulp')

const del = require('del')
const browserSync = require('browser-sync')

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()

const bs = browserSync.create()

const clean = () => {
  return del(['dist', 'temp'])
}

const style = () => {
  //                                      保存基础路径
  return src('src/assets/styles/*.scss', {base:'src'})
    // sass 认为  _*.scss 命名的文件都是主要文件中以来的文件所以不会单独转换一个css文件
    // expanded 完全展开  不设置的话 编译出来的文件不会完全展开
    .pipe(plugins.sass({outputStyle:'expanded'}))
    .pipe(dest('temp'))

  //bs不使用files属性
  //.pipe(bs.reload( { stream: true } ))

}

const script = () => {
  return src('src/assets/scripts/*.js',{base:'src'})
    .pipe(plugins.babel({presets: ['@babel/preset-env']}))
    .pipe(dest('temp'))

}

const data= {
  pkg:require('./package.json')
}

const page = () => {
  return src('src/*.html',{ base:'src'})
    .pipe(plugins.swig({data:data,cache:false}))
    .pipe(dest('temp'))
}

const image = () => {
  return src('src/assets/images/**',{ base: 'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/font/**',{ base: 'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

//将public文件拷贝过去
const extra = () => {
  return src('public/**',{ base: 'public'})
    .pipe(dest('dist'))
}

const server = () => {

  // 监听 发生变化执行任务
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  // 监听静态资源，减少构建次数
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
  ], bs.reload)

  bs.init({
    notify:  false,
    port: 3000,
    open: true,
    files:['temp/**'],
    server: {
      baseDir: ['temp','src','public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () => {
  return src('temp/*.html', {base:'temp'})
    // 修改文件引入地址
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    // 压缩生成文件
    // html js  css
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    // 读写流不能一致，否侧可能会产生读写冲突导致文件内容空白
    .pipe(dest('dist'))
}

const lintStage = () => {
  return src('src/assets/scripts/*.js',{base:'src'})
    // eslint（）将lint输出附加到“eslint”属性 以供其它模块使用
    .pipe(plugins.eslint())
    // format（）将lint结果输出到控制台。
    // 或者使用eslint.formatEach（）（参见文档）。
    .pipe(plugins.eslint.format())
    // 使进程退出时具有错误代码（1）
    // lint错误，最后将流和管道返回failAfterError。
    .pipe(plugins.eslint.failAfterError())
}

//组合任务 同时运行
const compile = parallel(style, script, page)

//生产环境构建
const build = series(clean, lintStage, parallel(series(compile,useref),image,font, extra) )

//开发环境构建
const serve = series(lintStage, compile, server)

const lint = series(lintStage)

module.exports = {
  clean,
  build,
  serve,
  lint
}
